#include <stdlib.h>
#include <stdio.h>

/*
调用函数时先求实参表达式的值再传给形参，如果实参表达式有Side Effect，那么这些Side Effect只发生一次。例如MAX(++a, ++b)，如果MAX是个真正的函数，a和b只增加一次。但如果MAX是上面那样的宏定义，则要展开成k = ((++a)>(++b)?(++a):(++b))，a和b就不一定是增加一次还是两次了。

即使实参没有Side Effect，使用函数式宏定义也往往会导致较低的代码执行效率。下面举一个极端的例子，也是个很有意思的例子。
*/

#define CONCAT con##cat
#define SSSS "ni "    "hao"
#define STR(s) #s
#define MAX(a, b) ((a)>(b)?(a):(b))

int a[] = { 99, 3, 5, 2, 1, 10, 18, 7, 6, 4, 45 };
static int i = 1;

int max(int n)
{
    printf ("%d\n", i++);
    return n == 0 ? a[0] : MAX(a[n], max(n-1));
}

int main(void)
{
    printf ("%d\n", max(10));
    printf ("%s\n", STR(Ni      hao));
    printf ("n" "fff" "\n");
    printf (SSSS "\n");
    printf (CONCAT "\n");
    return 0;
}

/*
这段代码从一个数组中找出最大的数，如果MAX是个真正的函数，这个算法就是从前到后遍历一遍数组，时间复杂度是Θ(n)，而现在MAX是这样一个函数式宏定义，思考一下这个算法的时间复杂度是多少？
最差的情况竟然是2的11次方次
*/
